package main

import (
	"fmt"
	"log"
	"net"
	"time"

	"github.com/BurntSushi/toml"
)

type Config struct {
	Servers []ServerConfig
}

type ServerConfig struct {
	Address      string `toml:"address"`
	MachineIDs   []int  `toml:"machine_ids"` // 每个服务器对应的机器编号数组
	SendInterval string `toml:"send_interval"`
}

var (
	connections    map[string]net.Conn // 服务器地址到连接的映射
	sequences      map[string]byte     // 每个服务器的序列号
	reconnectDelay = 5 * time.Second   // 重连延迟
)

func main() {
	// 读取配置文件
	var config Config
	if _, err := toml.DecodeFile("config.toml", &config); err != nil {
		log.Fatalf("Failed to read config file: %v", err)
	}

	// 初始化连接和序列号映射
	connections = make(map[string]net.Conn)
	sequences = make(map[string]byte)

	// 延迟关闭所有连接
	defer func() {
		for _, conn := range connections {
			if conn != nil {
				conn.Close()
			}
		}
	}()

	// 为每个服务器初始化连接
	for _, server := range config.Servers {
		if err := connectToServer(server.Address); err != nil {
			log.Printf("Failed to connect to server %s: %v, will try in the loop", server.Address, err)
		}
	}

	// 按顺序为每个服务器的每个机器编号发送 TCP 命令
	for {
		for _, server := range config.Servers {
			// 解析发送间隔
			interval, err := time.ParseDuration(server.SendInterval)
			if err != nil {
				log.Printf("Failed to parse send interval for server %s: %v, using default 1s", server.Address, err)
				interval = 1 * time.Second
			}

			for _, machineID := range server.MachineIDs {
				// 如果连接不存在或者已断开，尝试连接
				if connections[server.Address] == nil {
					if err := connectToServer(server.Address); err != nil {
						log.Printf("Failed to connect to server %s: %v, will retry later", server.Address, err)
						time.Sleep(reconnectDelay)
						continue
					}
				}

				// 获取当前服务器的序列号
				sequence := sequences[server.Address]

				// 生成命令
				command := buildCommand(sequence, byte(machineID))
				log.Printf("Sending command to server %s: %x (Sequence: %02X, MachineID: %02X)",
					server.Address, command, sequence, machineID)

				// 发送命令
				if err := sendTCPCommand(server.Address, command); err != nil {
					log.Printf("Failed to send command to server %s: %v", server.Address, err)
					// 尝试重连
					if err := reconnectToServer(server.Address); err != nil {
						log.Printf("Failed to reconnect to server %s: %v", server.Address, err)
					}
				}

				// 更新序列号
				sequences[server.Address] = sequence + 1

				// 等待指定的间隔时间
				time.Sleep(interval)
			}
		}
	}
}

// connectToServer 连接到 TCP 服务器
func connectToServer(address string) error {
	var err error
	conn, err := net.Dial("tcp", address)
	if err != nil {
		return fmt.Errorf("failed to connect to server: %v", err)
	}
	connections[address] = conn
	sequences[address] = 0 // 初始化序列号
	log.Printf("Connected to server at %s", address)
	return nil
}

// reconnectToServer 重连到 TCP 服务器
func reconnectToServer(address string) error {
	log.Printf("Reconnecting to server %s...", address)
	if connections[address] != nil {
		connections[address].Close() // 关闭旧连接
		connections[address] = nil
	}
	time.Sleep(reconnectDelay) // 等待重连延迟
	return connectToServer(address)
}

// sendTCPCommand 发送 TCP 命令
func sendTCPCommand(address string, command []byte) error {
	// 检查连接是否存在
	conn := connections[address]
	if conn == nil {
		return fmt.Errorf("connection to %s is not established", address)
	}

	// 设置发送超时时间为 3 秒
	if err := conn.SetWriteDeadline(time.Now().Add(3 * time.Second)); err != nil {
		return fmt.Errorf("failed to set write deadline: %v", err)
	}

	// 发送命令
	_, err := conn.Write(command)
	if err != nil {
		connections[address] = nil // 标记连接已断开
		return fmt.Errorf("failed to send command: %v", err)
	}

	return nil
}

// buildCommand 构造 TCP 命令
func buildCommand(sequence, machineID byte) []byte {
	// 固定前缀
	prefix := []byte{0x03, sequence}

	// 动态部分：固定值 000006 + 机器编号 + 固定值 0300000019
	//dynamic := []byte{0x00, 0x00, 0x00, 0x06, machineID, 0x03, 0x00, 0x00, 0x00, 0x19}
	dynamic := []byte{0x00, 0x00, 0x00, 0x06, machineID, 0x03, 0x00, 0x01, 0x00, 0x04} //01 03 00 01 00 04

	// 合并前缀和动态部分
	command := append(prefix, dynamic...)
	return command
}
